#ifndef OOPSMP_UTILS_GEOMETRY_JOINTS_JOINTS_H_
#define OOPSMP_UTILS_GEOMETRY_JOINTS_JOINTS_H_

#include "OOPSMP/Utils/General/Factory.H"

namespace OOPSMP {
	
	/**
	 *@brief Represents joint types as numbers
	 */
	enum JointType {
		INVALID = -1,
		TAIL,
		REVOLUTE,
		CYLINDRICAL,
		PRISMATIC,
		SPHERICAL
	};
	
	/**
	 *@brief Macro for class, class pointer, and const class pointer
	 *       declarations 
	 */
	ForwardClassDeclaration(Joints);
	
	/**
	 *@brief joints
	 */ 
	class Joints {

	public:
		
		/**
		  *@brief virtual functions, must be overridden in deriving classes
		  */ 
		virtual void	 setJointLimits( const double * min, const double * max ) = 0;
		virtual void	 getJointLimits( double * min, double * max ) const = 0;

		virtual bool	 isDoFAngle( int dof_id) const = 0;
		virtual int		 getNumDoFs() const = 0;
		
		virtual void	 getTransformationMatrix( double *link1_dims, double *link2_dims, const double * values, double * result ) const = 0;

		/**
		  *@brief Sets joint length to supplied value
		  *@param length joint length
		  */ 
		virtual void	 setJointLength( const double length ) { jointLength = length; }
		
		/**
		  *@brief Returns joint length
		  */ 
		virtual double	 getJointLength() const { return jointLength; }

		
		
	protected:
		
		/**
		  *@brief joint length
		  */
		double jointLength;
		
		/**
		  *@brief array of minimum values for joint dofs
		  */
		double * jointLimitsMin;
		
		/**
		  *@brief array of maximum values for joint dofs
		  */
		double * jointLimitsMax;

	};
	
	/**
     *@brief Declare factory and specify in source file the functions that should
     *       be registered for plug-and-play functionality
     */
	DeclareNoInstanceFactory(Joints, Factory);

}

#endif
